﻿
using System;


namespace Boilen.Primitives.Members {

    /// <summary>
    /// Writes code for an accessor (i.e. property, event).
    /// </summary>
    public sealed class AccessorMember : HelpedMember {

        private BlockMember observeMember_;
        private BlockMember updateMember_;


        /// <inheritdoc/>
        public override Extensions UsedExtensions {
            get {
                return base.UsedExtensions
                     | Util.GetUsedExtensions( this.ObserveMember, this.UpdateMember );
            }
        }

        /// <summary>
        /// Gets or sets the member used to observe the accessor.
        /// </summary>
        public BlockMember ObserveMember {
            get { return this.observeMember_; }
            set {
                this.observeMember_ = value;
                this.UpdateDoc( value );
            }
        }

        /// <summary>
        /// Gets or sets the member used to update the accessor.
        /// </summary>
        public BlockMember UpdateMember {
            get { return this.updateMember_; }
            set {
                this.updateMember_ = value;
                this.UpdateDoc( value );
            }
        }


        /// <summary>
        /// Initializes a new <see cref="AccessorMember"/> instance.
        /// </summary>
        /// <param name="name">The name of the accessor.</param>
        /// <param name="type">The type of the accessor.</param>
        public AccessorMember( string name, string type )
            : base( name, type, "public" ) { }


        /// <inheritdoc/>
        protected override void WriteCore( ICodeWriter writer ) {
            writer.WriteLine( "{0} {1} {2}", this.Modifiers, this.Type, this.Name );

            var observe = this.ObserveMember ?? Member.Empty;
            var update = this.UpdateMember ?? Member.Empty;

            using( Enclose.Braces( writer ) ) {
                observe.Write( writer );
                update.Write( writer );
            }
        }


        private void UpdateDoc( BlockMember block ) {
            if( block != null && this.Doc != null )
                this.Doc.AddExceptions( block.Guards );
        }

    }

}
